package org.road0329.tools.proto_parse_tool.ems.xintian.utils;

import org.road0329.tools.proto_parse_tool.chargingpile.MsgDcsResult;
import org.road0329.tools.proto_parse_tool.ems.dataobject.gw.GwItemData;
import org.road0329.tools.proto_parse_tool.ems.dataobject.gw.ReqDataComm;
import org.road0329.tools.proto_parse_tool.ems.dataobject.gw.afn0D.Req2ndDataParam;
import org.road0329.tools.proto_parse_tool.utils.NumberUtil;
import org.road0329.tools.proto_parse_tool.utils.ProtocolGW_09Util;
import org.road0329.tools.proto_parse_tool.utils.ProtocolUtils;
import org.road0329.tools.proto_parse_tool.utils.ProtocolXinTianUtil;
import org.road0329.tools.proto_parse_tool.vo.xtkj.MeterDataVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.CommunicationException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2018-09-20.
 */
public class XinTianClassTwoUtil {

    private static Logger logger = LoggerFactory.getLogger(XinTianClassTwoUtil.class);
    private static final int TARIFF_NUM_DEFAULT = 4;// 目前集中器按费率数=4 上送任务数据

    public byte[] packClassTwoCommand(List<GwItemData> itemList) throws CommunicationException {
        String data = "";
        for (GwItemData itemData : itemList) {
            int fn = itemData.getFn();
            data = ProtocolGW_09Util.getDTDAFrame(itemData.getPn(), itemData.getFn()) + data;
            int len = 0;
            if (fn == 1 || fn == 2 || fn == 3 || fn == 4 || fn == 5 || fn == 6 || fn == 7 || fn == 8 || fn == 9 || fn == 10 || fn == 11 || fn == 25 || fn == 26 || fn == 27 || fn == 28 || fn == 29 ||
                    fn == 30 || fn == 31 || fn == 32 || fn == 41 || fn == 42 || fn == 43 || fn == 45 || fn == 49 || fn == 50 || fn == 53 || fn == 57 || fn == 58 || fn == 59 || fn == 153
                    || fn == 154 || fn == 155 || fn == 156 || fn == 161 || fn == 162 || fn == 163 || fn == 164 || fn == 165 || fn == 166 || fn == 167 || fn == 168 || fn == 169 || fn == 170
                    || fn == 171 || fn == 172 || fn == 173 || fn == 174 || fn == 175 || fn == 176 || fn == 185 || fn == 186 || fn == 187 || fn == 188 || fn == 189 || fn == 190 || fn == 191
                    || fn == 192 || fn == 209) {
                data = packTd_dFrame(data, itemData);
            } else if (fn == 17 || fn == 18 || fn == 19 || fn == 20 || fn == 21 || fn == 22 || fn == 23 || fn == 24 || fn == 33 || fn == 34 || fn == 35 || fn == 36 || fn == 37 || fn == 38 || fn == 39 ||
                    fn == 44 || fn == 46 || fn == 51 || fn == 52 || fn == 54 || fn == 60 || fn == 61 || fn == 62 || fn == 65 || fn == 66 || fn == 113 || fn == 114 || fn == 115 || fn == 116 || fn == 117 || fn == 118
                    || fn == 121 || fn == 122 || fn == 123 || fn == 157 || fn == 158 || fn == 159 || fn == 160 || fn == 177 || fn == 178 || fn == 179 || fn == 180 || fn == 181 || fn == 182 || fn == 183
                    || fn == 184 || fn == 193 || fn == 194 || fn == 195 || fn == 196 || fn == 201 || fn == 202 || fn == 203 || fn == 204 || fn == 205 || fn == 206 || fn == 207 || fn == 208 || fn == 213
                    || fn == 214 || fn == 215 || fn == 216) {
                data = packTd_mFrame(data, itemData);
            } else if (fn == 73 || fn == 74 || fn == 75 || fn == 76 || fn == 81 || fn == 82 || fn == 83 || fn == 84 || fn == 85 || fn == 86 || fn == 87 || fn == 88 || fn == 89 || fn == 90 ||
                    fn == 91 || fn == 92 || fn == 93 || fn == 94 || fn == 95 || fn == 97 || fn == 98 || fn == 99 || fn == 100 || fn == 101 || fn == 102 || fn == 103 || fn == 104 || fn == 105 || fn == 106
                    || fn == 107 || fn == 108 || fn == 109 || fn == 110 || fn == 145 || fn == 146 || fn == 147 || fn == 148) {
                data = packTd_cFrame(data, itemData);
            }
        }
        return ProtocolUtils.StringToHex(data);
    }

    private String packTd_cFrame(String data, GwItemData itemData) {
        Req2ndDataParam param = (Req2ndDataParam) itemData.getData();
        data = ProtocolGW_09Util.pickA15(param.getStarttime()) + data;
        data = NumberUtil.num2PadString((int) param.getFreezedensity(), 16, 2, "0") + data;
        data = NumberUtil.num2PadString((int) param.getDatanum(), 16, 2, "0") + data;
        return data;
    }

    private String packTd_dFrame(String data, GwItemData itemData) {
        Req2ndDataParam param = (Req2ndDataParam) itemData.getData();
        data = ProtocolGW_09Util.pickA20(param.getStarttime()) + data;
        return data;
    }

    private String packTd_mFrame(String data, GwItemData itemData) {
        Req2ndDataParam param = (Req2ndDataParam) itemData.getData();
        data = ProtocolGW_09Util.pickA21(param.getStarttime()) + data;
        return data;
    }

    public static MsgDcsResult parseClassTwoData(byte[] msg, int from, boolean acd) throws CommunicationException {
        String commAddr = String.format("%02X%02X%02X%02X", msg[8], msg[7], msg[10], msg[9]);
        int index = from;
        int fixlen = (msg[index] & 0x80) == 0 ? 2 : 8;
        if (acd) {
            fixlen += 2;
        }
        index++;
        MsgDcsResult gwResult = new MsgDcsResult();
        List<GwItemData> gwItemList = new ArrayList<GwItemData>();
        while ((index + fixlen) < msg.length) {
            int fn = msg[index] & 0xff;
            index++;
            GwItemData item = new GwItemData();
            item.setFn(fn);
            ReqDataComm reqDataComm;
            int n;
            switch (fn) {
                case 1:
                case 2:
                    Map<String,Object> parseResult = parseReport(msg, index);
                    item.setData(parseResult);
                    int len = (int)parseResult.get("len");
                    item.setSuccess(true);
                    index += len;
                    break;
                default:
                    throw new CommunicationException("376.1协议处理==> 二类类数据中找不到FN=" + fn + "的处理方法");
            }
            gwItemList.add(item);//新天平台数据上报， 移除havingTask检查
        }
        gwResult.setData(gwItemList);
        gwResult.setSuccess(true);
        gwResult.setMessage("成功");
        return gwResult;
    }

    private static Map<String, Object> parseReport(byte[] byteValue, int index) {
        Map<String, Object> result = new LinkedHashMap<>();
        int oldIndex = index;
        int groupNum = ProtocolUtils.convertToUnsignedInt(byteValue[index + 1], byteValue[index]);
        result.put("groupNum", groupNum);
        index += 2;
        int groupIndex = ProtocolUtils.convertToUnsignedInt(byteValue[index + 1], byteValue[index]);
        result.put("groupIndex", groupIndex);
        index += 2;
        int meterNum = byteValue[index] & 0xff;
        result.put("meterNum", meterNum);
        index++;
        String date = ProtocolUtils.getStringDateByBCD(byteValue, index, 3);
        result.put("readDate", date);
        index += 3;
        int meterType = byteValue[index] & 0xff;
        result.put("meterType", meterType);
        index++;
        logger.debug("F1 or F2 groupNum:{}, groupIndex:{}, meterNum:{}, meterType:{}, date:{}", groupNum, groupIndex, meterNum, meterType, date);
        List<MeterDataVO> meterDataList = new ArrayList<>(meterNum);
        for (int i = 0; i < meterNum; i++) {
            meterDataList.add(ProtocolXinTianUtil.parseData(byteValue, index));
            index += 29;
        }
        result.put("meterDataList", meterDataList);
        int len = index - oldIndex;
        result.put("len", len);
        return result;
    }
}
